//
//  BCDebugCom.m
//  Pod
//
//  Created by Basic on 2017/3/14.
//  Copyright © 2017年 naruto. All rights reserved.
//

#import "BCDebugCom.h"
#import "BCDebugPage.h"
#import "BCDebugEnterView.h"
#import "BCDebugKitPublic.h"
#import "BCDebugKitProtocol.h"

#import <BCFoundation/BCFoundationUtils.h>
#import <objc/message.h>

@interface BCDebugCom()
/// 容器view
@property (nonatomic, weak) UIView  *bcContainerView;
/// 调试入口
@property (nonatomic, strong) BCDebugEnterView  *bcDebugEnter;
/// 具体的配置对象
@property (nonatomic, strong) NSMutableArray<id<BCDebugKitProtocol>> *debugConfigs;
/// 具体的配置类的 内部初始化
@property (nonatomic, strong) NSMutableArray<Class> *debugConfigClses;

/// rootNavcDebug 的父 vc
@property (nonatomic, weak) UIViewController    *bcContanerVC;
/// debug 的root
@property (nonatomic, strong, readwrite) UINavigationController     *rootNavcDebug;
@end

@implementation BCDebugCom
///MARK: - system
static BCDebugCom *kBCDebugComInstance = nil;
+ (instancetype)sharedInstance {
    static dispatch_once_t kBCDebugOnceToken;
    dispatch_once(&kBCDebugOnceToken, ^{
        kBCDebugComInstance = [[BCDebugCom alloc] init];
    });
    return kBCDebugComInstance;
}
- (instancetype)init {
    self = [super init];
    if (self) {
        _debugConfigs = [[NSMutableArray alloc] init];
        _debugConfigClses = [[NSMutableArray alloc] init];
    }
    return self;
}
-(void)dealloc {
    _bcDebugEnter = nil;
    kBCDebugComInstance = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

///MARK: - getter
-(BCDebugEnterView *)bcDebugEnter {
    if (!_bcDebugEnter) {
        CGFloat kLeft = kBCSCREEN_WIDTH - 60;
        CGFloat kTop = kBCNAVBAR_HEIGHT;
        _bcDebugEnter = [[BCDebugEnterView alloc] initWithFrame:CGRectMake(kLeft, kTop, 60, 60)];
        @BCWeakify(self);
        [_bcDebugEnter setClickBlock:^{
            @BCStrongify(self);
            [self onDebugEnterClick:nil];
        }];
    }
    return _bcDebugEnter;
}
///MARK: - setter
- (void)setUserConfig:(id<BCDebugKitProtocol>)userConfig {
    id objDebugConfig = [[NSClassFromString(@"BCDebugUserConfig") alloc] init];
    [objDebugConfig setValue:userConfig forKey:@"configDelegate"];
    [self registerConfigObject:objDebugConfig];
}
- (void)setDeviceConfig:(id<BCDebugKitProtocol>)deviceConfig {
    id objDebugConfig = [[NSClassFromString(@"BCDebugDeviceConfig") alloc] init];
    [objDebugConfig setValue:deviceConfig forKey:@"configDelegate"];
    [self registerConfigObject:objDebugConfig];
}

///MARK: - 开始注册
+ (void)startDebug:(UIView *)view {
    if(!view){
        view = [[[UIApplication sharedApplication] delegate] window];
    }
    [BCDebugCom sharedInstance].bcContainerView = view;
    [[BCDebugCom sharedInstance] bc_setup];
    
//    [[BCDebugCom sharedInstance] registerConfigName:@"BCDebugUserConfig"];
//    [[BCDebugCom sharedInstance] registerConfigName:@"BCDebugDeviceConfig"];
    [[BCDebugCom sharedInstance] registerConfigName:@"BCDebugFpsConfig"];
    [[BCDebugCom sharedInstance] registerConfigName:@"BCFileExploreConfig"];

}

//MARK: - 环境配置
+ (NSInteger)currentENV {
    id deviceCls = NSClassFromString(@"BCDebugDeviceConfig");
    if ([deviceCls respondsToSelector:NSSelectorFromString(@"currentENV")]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        NSInteger currentEnv = ((NSInteger (*)(id, SEL))(void *) objc_msgSend)((id)deviceCls, NSSelectorFromString(@"currentENV"));
#pragma clang diagnostic pop
        return currentEnv;
    }
    // 默认线上环境
    return 0; 
}

///MARK: - private
- (void)bc_setup {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAppDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onApmUpdate:) name:(NSNotificationName)BCDebugKit_ApmUpdate object:nil];
    [self.bcContainerView addSubview:self.bcDebugEnter];
}

///MARK: - Event
- (void)onDebugEnterClick:(UIButton *)sender {
    if (self.rootNavcDebug) {
        [self.rootNavcDebug dismissViewControllerAnimated:YES completion:nil];
        self.rootNavcDebug = nil;
        return;
    }
    //判断原来是否显示
    BCWeakObj(self);
    BCDebugPage *debugPage = [[BCDebugPage alloc] initWithHideAction:^{
        BCStrongObj(self);
        self.rootNavcDebug = nil;
    }];
    //显示配置页面
    [[[UIApplication sharedApplication] keyWindow] endEditing:YES];
    debugPage.debugConfigClses = self.debugConfigClses;
    debugPage.debugConfigs = self.debugConfigs;
    self.rootNavcDebug = [[UINavigationController alloc] initWithRootViewController:debugPage];
    self.rootNavcDebug.modalPresentationStyle = UIModalPresentationFullScreen;
    //判断跳转方式
    UIViewController *rootVC = [self bcdebug_topPage];
    [rootVC presentViewController:self.rootNavcDebug animated:YES completion:nil];
    _bcContanerVC = rootVC;
}

///MARK: - notifcation
- (void)onAppDidBecomeActive:(NSNotification *)notif {
    if (self.bcDebugEnter && self.bcContainerView) {
        [self.bcContainerView bringSubviewToFront:self.bcDebugEnter];
    }
}
- (void)onApmUpdate:(NSNotification *)notif {
    NSDictionary *userInfo = notif.userInfo;
    NSNumber *fps = userInfo[@"fps"];
    NSNumber *ram = userInfo[@"ram"];
    NSNumber *cpu = userInfo[@"cpu"];
    self.bcDebugEnter.fps = (fps)?[fps integerValue]:-1;
    self.bcDebugEnter.ram = (ram)?[ram floatValue]:-1;
    self.bcDebugEnter.cpu = (cpu)?[cpu integerValue]:-1;
    [self.bcDebugEnter reloadData];
}

///MARK: - 注册 配置 class
- (void)registerConfigName:(NSString *)strClsConfig {
    if (!strClsConfig) {
        return;
    }
    Class clsConfig = NSClassFromString(strClsConfig);
    if(!clsConfig){
#ifdef DEBUG
        NSLog(@"BCDebugCom registerConfig error:%@ not exsit",strClsConfig);
#endif
        return;
    }
    //load 每个调试模块
    if ([clsConfig conformsToProtocol:@protocol(BCDebugKitProtocol)] && [clsConfig respondsToSelector:@selector(bcDebugWillLoad)]) {
        ((void (*)(id, SEL))(void *) objc_msgSend)((id)clsConfig, @selector(bcDebugWillLoad));
    }
    if(![self.debugConfigClses containsObject:clsConfig]){
        [self.debugConfigClses addObject:clsConfig];
    }
}
- (void)registerConfigObject:(id<BCDebugKitProtocol>)objClsConfig {
    if (!objClsConfig) {
        return;
    }
    //load 每个调试模块
    if ([objClsConfig.class respondsToSelector:@selector(bcDebugWillLoad)]) {
        [objClsConfig.class bcDebugWillLoad];
    }
    if(![self.debugConfigs containsObject:objClsConfig]){
        [self.debugConfigs addObject:objClsConfig];
    }
}


///MARK: - top page
- (UIViewController *)bcdebug_topPage {
    UIViewController *vcRoot = [[[UIApplication sharedApplication] delegate] window].rootViewController;
    return [self bcdebug_topViewController:vcRoot];
}
- (UIViewController *)bcdebug_topViewController:(UIViewController *)viewController {
    if ([viewController isKindOfClass:[UINavigationController class]]) {
        return [self bcdebug_topViewController:[(UINavigationController *)viewController topViewController]];
    }
    else if ([viewController isKindOfClass:[UITabBarController class]]) {
        return [self bcdebug_topViewController:[(UITabBarController *)viewController selectedViewController]];
    }
    else if (viewController.presentedViewController) {
        return [self bcdebug_topViewController:viewController.presentedViewController];
    }
    return  viewController;
}

@end
